﻿/**
 * WROTE A LOT OF CODE THIS MORNING
 * TO DO:
 * Complete as many methods as you can
 * The goal is to be finished by tomorrow afternoon but we'll just have
 * to see about that.
 * I've done quite a bit so only the really technical parts are left.
 * 
 * If I'm in class tomorrow I'll be there to help out, if not
 * just e-mail me with questions
 * 
 * Have fun :D
 * 
 * Barry
 **/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using ProgramUtilities;

namespace ConsolePacman
{
    class Program
    {
        public static void Main(string[] args)
        {
            using (Game game = new Game())
            {
                game.Run();
            }
        }

        public struct Point
        {
            public int X, Y;
            private int p;
            private Point CurrentPosition;

            public Point(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }

            public Point(int p, Point CurrentPosition)
            {
                // TODO: Complete member initialization
                this.p = p;
                this.CurrentPosition = CurrentPosition;
            }
        }

        public class Game : IDisposable
        {
            public int[,] Level;
            public Point CurrentPosition;
            public Point LastPosition;
            public bool InGame, IsDone, Exit, GameOver;
            public string Space;
            public Point[] ghosts;

            public Game()
            {
                Level = new int[30,60];
                Exit = false;
            }

            public void Run()
            {
                ShowLogo();
                Thread.Sleep(1000);
                do
                {
                    ShowLogo();
                    ShowMenu();
                } while (!Exit);
            }

            public void ShowMenu()
            {
                Console.WriteLine("\n\n");
                Console.WriteLine(Space +"Welcome to Console Pacman: ");
                Console.WriteLine(Space + "1: Show Instructions");
                Console.WriteLine(Space + "2: Play Game");
                Console.WriteLine(Space + "3: Game Editor");
                Console.WriteLine(Space + "4: Exit");
                handleSelection(Utils.GetNumber("Enter your selection: "));

            }

            public void ShowLogo()
            {
                Console.Clear();
                int Spaces = Console.WindowWidth / 4;
                Space = "";
                for (int i = 0; i < Spaces; ++i) Space += " ";

                Console.WriteLine(Space + @".-. .-. .-. .  . .-. . .");
                Console.WriteLine(Space + @"|-' |-| |   |\/| |-| |\|");
                Console.WriteLine(Space + @"'   ` ' `-' '  ` ` ' ' `");
                Console.WriteLine(Space + @"                        Group B");
            }

            public void handleSelection(int selection)
            {
                //If selection is Exit then,
                if (selection == 4)
                {
                    Exit = true;
                }
                //Else if selection is Instructions then,
                else if (selection == 1)
                {
                    //ShowInstructions
                    showInstructions();
                }
                //Else if selection is Editor then,
                else if (selection == 3)
                {
                    //ShowEditor
                    showEditor();
                }
                //Else If selection is Game then,
                else if (selection == 2)
                {
                    //Play Game?
                    playGame();
                }
                else
                {
                    Console.WriteLine("Incorrect Selection");
                }
            }


            public void showInstructions()
            {
                //print instructions
                Console.Clear();
                Console.WriteLine(Space + "How to play Console Pacman");
                Console.WriteLine();
                Console.WriteLine(Space + "Play Game: ");
                Console.WriteLine(Space + "Play Pacman in your console");
                Console.WriteLine(Space + "Use arrow keys to move");
                Console.WriteLine(Space + "Run from ghosts");
                Console.WriteLine(Space + "Eat Pellets");
                Console.WriteLine();
                Console.WriteLine(Space + "Edit Level: ");
                Console.WriteLine(Space + "Create your very own Pacman Level");
                Console.WriteLine(Space + "Press W to create Walls");
                Console.WriteLine(Space + "Press P to create Pacman Spawn Point");
                Console.WriteLine(Space + "Press G to create Ghost Spawn");
                Console.WriteLine(Space + "Press . to create pellet");
                Console.ReadLine();
            }

            public void showEditor()
            {
                //InitializeEditor
                intializeEditor();
                //Let IsDone = false
                bool IsDone = false;

                //do . . .
                do
                {
                    //DrawLevel
                    drawLevel();

                    //If Key is was pressed
                    if (Console.KeyAvailable)
                    {
                        //GetInput
                        getInput();
                        //UpdateLevel
                        updateLevel();
                    }
                }
                //until IsDone
                while (!IsDone);
            }
            public void intializeEditor()
            {
                //let Level be a  30 column by 50 row array
                Level = new int[30, 20];
                //let CurrentPosition be 0,0
                CurrentPosition = new Point(0,0);
                //let LastPosition be 0,0
                LastPosition = new Point(0,0);
                //let InGame be false
                InGame = false;
                //let IsDone be false
                IsDone = false;
            }

            public void drawLevel()
            {
                Thread.Sleep(300);
                Console.Clear();
                //for each row in Level . . .
                for (int i = 0; i < Level.GetLength(0); ++i )
                {
                    //for each column in row . . .
                    for (int j = 0; j < Level.GetLength(1); ++j)
                    {
                        //PrintValue
                        printValue(Level[i, j]);
                    }
                    //print newline
                    Console.Write("\n");
                }
            }

            public void printValue(int index)
            {
                string[] values;

                //if InGame then,
                if (InGame)
                {
                    //let array values be ‘[ ], [#],[ ],[ ],[.],[*]’
                    values = new String[6] { "[ ]", "[#]", "[ ]", "[ ]", "[.]", "[*]" };
                }
                else
                {
                    //else in editor then,
                    //let array values be ‘[ ], [#],[G],[P],[.],[*]’
                    values = new String[6] { "[ ]", "[#]", "[G]", "[P]", "[.]", "[*]" };
                }

                
                //print values[index]
                Console.Write(values[index]);
            }

            public void getInput()
            {
                //let KeyValue be GetKeyValue
                ConsoleKeyInfo keyValue = Console.ReadKey();
                //Input(KeyValue)
                input(keyValue.Key);
            }

            public void input(ConsoleKey keyValue)
            {
                //if KeyValue is Left, Right, Up, or Down then,
                if (keyValue == ConsoleKey.LeftArrow || keyValue == ConsoleKey.UpArrow || keyValue == ConsoleKey.DownArrow || keyValue == ConsoleKey.RightArrow)
                {
                    //Move(KeyValue)
                    move(keyValue);
                }
                //if not InGame
                if (!InGame)
                {
                    //if KeyValue is G,P,*, or . then,
                    if (keyValue == ConsoleKey.G || keyValue == ConsoleKey.P || keyValue == ConsoleKey.D8 || keyValue == ConsoleKey.OemPeriod)
                    {
                        //SetSelection(KeyValue)
                        setSelection(keyValue);
                    }
                    else if (keyValue == ConsoleKey.Escape)
                    {
                        //else if KeyValue is Escape then,
                        //let IsDone be true
                        IsDone = true;
                    }
                }
            }

            public void move(ConsoleKey keyValue)
            {
                //if KeyValue is Up then,
                if (keyValue == ConsoleKey.UpArrow)
                {
                    //let CurrentPosition be current’s X ,  current’s Y - 1
                    CurrentPosition = new Point(CurrentPosition.X, CurrentPosition.Y - 1);
                }
                //if KeyValue is Down then,
                if (keyValue == ConsoleKey.DownArrow)
                {
                    //let CurrentPosition be current’s X, current’s Y + 1
                    CurrentPosition = new Point(CurrentPosition.X, CurrentPosition.Y + 1);
                }
                //if KeyValue is Left then,
                if (keyValue == ConsoleKey.LeftArrow)
                {
                    //let CurrentPosition be current’s X - 1, current’s Y
                    CurrentPosition = new Point(CurrentPosition.X - 1, CurrentPosition.Y);
                }
                //if KeyValue is Right then,
                if (keyValue == ConsoleKey.RightArrow)
                {
                    //let CurrentPosition be current’s X + 1, currents Y
                    CurrentPosition = new Point(CurrentPosition.X + 1, CurrentPosition.Y);
                }
            }
            public void setSelection(ConsoleKey keyValue)
            {
                //let selectionValues be a dictionary
                //where a letter is a key and a number is the value {[G,0],[P,1],[*,2],[.,3]}

                int selection = 0;

                if (keyValue == ConsoleKey.G) selection = 2;
                else if (keyValue == ConsoleKey.G) selection = 3;
                else if (keyValue == ConsoleKey.D8) selection = 4;
                else if (keyValue == ConsoleKey.OemPeriod) selection = 5;

                //let the value in Level at CurrentPosition be selectionValues[KeyValue]
                Level[CurrentPosition.Y, CurrentPosition.X] = selection;
            }

            public void playGame()
            {
                //InitGame
                InitGame();
                //until gameOver . . .
                do
                {
                    //UpdateLevel
                    updateLevel();
                    //DrawLevel
                    drawLevel();
                } while (!GameOver);
            }

            public void InitGame()
            {
            
            }

            public void updateLevel()
            {
                //UpdatePlayer
                updatePlayer();
                //UpdateAi
                updateAI();
                //CheckForDeath
                
            }

            public void updatePlayer()
            {
                //GameInput
                gameInput();
                //CheckForCollision
                checkForCollision();
            }

            public void updateAI()
            {
                //PathFind
                pathFind();
            }

            /**
             * If the value of whatever's at the current position is a wall
             * Make currentposition be previous position
             **/
            public void checkForCollision()
            {
                //CheckForCollision
                //Get pacman’s direction
                //if pacman is facing a wall then,
                //return true
                //else pacman is not facing a wall,
                //return false
            }

            public bool above(Point ghost)
            {
                bool isAbove = false;

                if (ghost.Y > CurrentPosition.Y)
                    isAbove = true;

                return isAbove;
            }
            public bool below(Point ghost)
            {
                bool isBelow = false;

                if (ghost.Y < CurrentPosition.Y)
                    isBelow = true;

                return isBelow;
            }

            /**
             * TODO:
             * Try to get this working, if not we'll push it together wednesday
             **/
            public void pathFind()
            {
                //for each ghost in ghosts . . .
                foreach (Point ghost in ghosts)
                {
                    //FindPacman
                    this.findPacman();
                    //if ghostPosition is Above(CurrentPosition) or Below(CurrentPosition),
                    if (this.above(ghost) || this.below(ghost))
                    {
                        //if not onWall,
                        //StepX(left)
                        //else onWall,
                        //StepY
                    }
                 }
            }

            public int distance(Point Ghost, int direction)
            {
                int distance = 0;

                for (int offset = 0; ; offset += direction)
                {
                    int xLoc = offset + Ghost.X;

                    if (xLoc < 0 || xLoc > Level.Length)
                        break;
                    else
                        distance++;

                }

                return distance;
            }

            public bool findShortestWall(Point ghost)
            {
                //let result be false
                bool result = false;
                //if Distance(Left) is less than Distance(Right),
                if (this.distance(ghost, -1) < this.distance(ghost, 1))
                //let result be true
                    result = true;

                //return result
                return result;
            }

            public void stepX()
            {
                //if FindShortestWall,
                //let ghostPosition be ghostPosition X - 1, ghostPosition Y
                //else right,
                //let ghostPosition be ghostPosition X + 1, ghostPosition Y
            }

            public void stepY()
            {
                //if Above,
                //let ghostPosition be ghostPosition X, ghostPosition Y + 1
                //else Below
                //let ghostPosition be ghostPosition X, ghostPosition Y - 1
            }

            public void findPacman()
            {

            }

            public void gameInput(ConsoleKey keyValue)
            {
                //if KeyValue is W then,
                if (keyValue == ConsoleKey.W)
                    //let CurrentPosition be current x and y - 1
                    this.CurrentPosition = new Point(CurrentPosition.X, CurrentPosition.Y - 1);
                //else if keyValue is s then,
                else if (keyValue == ConsoleKey.S)
                    //let CurrentPosition be current x and y + 1
                    this.CurrentPosition = new Point(CurrentPosition.X, CurrentPosition.Y + 1);
                //else if keyValue is a then,
                else if (keyValue == ConsoleKey.A)
                    //let current position be current x -1 and y
                    this.CurrentPosition = new Point(CurrentPosition.X - 1, CurrentPosition);
                //else if keyValue is d then,
                else if (keyValue == ConsoleKey.D)
                    //let current position be current x + 1 and y
                    this.CurrentPosition = new Point(CurrentPosition.X + 1, CurrentPosition);
                //if KeyValye is ESC then,
                else if (keyValue == ConsoleKey.Escape)
                    //let gameOver be true
                    this.GameOver = true;
            }

            public void Dispose()
            {
                
            }
        }
    }
}
